package com.majie.utils.utils.spring;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.boot.env.YamlPropertySourceLoader;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

import java.io.IOException;

/**
 * 该实现可以加载任意文件并将它们添加到环境中
 * /META-INF/spring.factories下添加
 * org.springframework.boot.env.EnvironmentPostProcessor=com.majie.configuartion.EnvironmentPostProcessorExample
 * <p>
 * <p>
 * 虽然在@SpringBootApplication上使用@PropertySource似乎是在环境中加载自定义资源的一种方便而简单的方法，
 * 但我们不建议这样做，因为Spring Boot会在刷新ApplicationContext之前准备环境。
 * 使用@PropertySource定义的任何键加载太晚都不会对自动配置产生任何影响
 *
 * @PropertySource 注解, 加载yml似乎不起效, 但是加载properties是ok的
 */
public class EnvironmentPostProcessorExample implements EnvironmentPostProcessor {

    private final YamlPropertySourceLoader loader = new YamlPropertySourceLoader();

    /**
     * 加载properties或者xml
     */
//    private final PropertiesPropertySourceLoader loader = new PropertiesPropertySourceLoader();
    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment,
                                       SpringApplication application) {
        Resource path = new ClassPathResource("my.yml");    //resources下的路径
        PropertySource<?> propertySource = loadYaml(path);
        environment.getPropertySources().addLast(propertySource);
    }

    private PropertySource<?> loadYaml(Resource path) {
        if (!path.exists()) {
            throw new IllegalArgumentException("Resource " + path + " does not exist");
        }
        try {
            return this.loader.load("custom-resource", path).get(0);
        } catch (IOException ex) {
            throw new IllegalStateException(
                    "Failed to load yaml configuration from " + path, ex);
        }
    }

}